package com.aura.common.redis.service;

import com.aura.common.core.utils.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @ClassName RedisHashService
 * @Description
 * @Author ZJX
 * @Date 2025/7/19 23:55
 * @Version 1.0
 **/
@Component
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public class RedisHashService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 缓存Map数据
     * @param key key
     * @param dataMap map
     * @param <T> 对象类型
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap){
        if (dataMap != null){
            redisTemplate.opsForHash().putAll(key,dataMap);
        }
    }

    /**
     * 往 Redis 的 Hash 结构中写入一个字段值
     * Redis 的 Hash 相当于一个“嵌套 Map”，结构是： key -> (hKey -> value)
     * 举例：
     * - 存储用户信息：key = "user:1001"，hKey = "name"，value = "Alice"
     * - 对应 Redis 命令：HSET user:1001 name "Alice"
     *
     * @param key Redis 主键（外层 key，比如 user:1001）
     * @param field Hash 内部字段名（比如 name、age）
     * @param value 值（字段值）
     * @param <T> 值的类型
     */
    public <T> void setCacheMapValue(final String key, final String field, final T value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    /**
     * 删除Hash中的某条数据
     *
     * 返回值说明：
     * - 原始返回 Long，表示删除数量
     * - 封装为 boolean：删除成功返回 true，字段不存在返回 false   更直观
     * @param key  Redis键
     * @param field Hash键
     * @return 是否成功
     */
    public <T> boolean deleteCacheMapValue(final String key, final String field){
        return redisTemplate.opsForHash().delete(key,field) > 0;
    }


    /**
     * 获取 Redis Hash 中的所有字段及其对应值（支持复杂泛型）
     * 作用：将指定 key 对应的整个 Hash 映射为 Map 返回
     *
     * @param key Redis 主键
     * @param typeReference 类型模板（支持嵌套泛型）
     * @return Hash 对应的 Map
     * @param <T> 值类型
     */
    public <T> Map<String, T> getCacheMap(final String key, TypeReference<Map<String, T>> typeReference) {
        Map data = redisTemplate.opsForHash().entries(key);
        return JsonUtil.string2Obj(JsonUtil.obj2String(data), typeReference);
    }


    /**
     * 获取Hash中的单个数据
     * @param key Redis键
     * @param field Hash键
     * @return Hash中的对象
     * @param <T> 对象类型
     */
    public <T> T getCacheMapValue(final String key, final String field){
        return (T) redisTemplate.opsForHash().get(key, field);
    }

    /**
     * 获取Hash中的多个数据
     *
     * @param key Redis键
     * @param field Hash键集合
     * @param typeReference 对象模板
     * @return 获取的多个数据的集合
     * @param <T> 对象类型
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<String> field, TypeReference<List<T>> typeReference) {
        List multiGet = redisTemplate.opsForHash().multiGet(key, field);
        return JsonUtil.string2Obj(JsonUtil.obj2String(multiGet),typeReference);
    }

    /**
     * 判断 Hash 中是否存在指定字段
     *
     * @param key Redis 主键
     * @param field 字段名
     * @return 是否存在
     */
    public boolean hasHashKey(final String key, final String field) {
        return redisTemplate.opsForHash().hasKey(key, field);
    }


    /**
     * 获取 Hash 中字段总数
     *
     * @param key Redis 主键
     * @return 字段数量
     */
    public long getHashSize(final String key) {
        Long size = redisTemplate.opsForHash().size(key);
        return size == null ? 0L : size;
    }

    /**
     * 删除整个 Hash（删除 key）
     *
     * @param key Redis 主键
     * @return 是否成功
     */
    public boolean deleteHash(final String key) {
        return Boolean.TRUE.equals(redisTemplate.delete(key));
    }

}
